package com.yang.core.api;

import com.yang.core.extension.ExtensionRegistry;
import com.yang.core.extension.RestClientExtension;
import com.yang.core.interceptor.LoggingInterceptor;
import com.yang.core.config.RestClientConfig;
import com.yang.core.model.RequestContext;
import com.yang.core.model.ResponseContext;
import com.yang.core.model.RetryPolicy;
import com.yang.core.api.RestClient;
import lombok.extern.slf4j.Slf4j;

import java.net.URI;
import java.time.Duration;
import java.util.*;
import java.util.function.Consumer;

/**
 * RestClient构建器
 * 提供流畅的API设计，支持链式调用
 */
@Slf4j
public class RestClientBuilder {

    // 基础配置
    private String baseUrl = "";
    private String userAgent = "RestClient/2.0";
    private String charset = "UTF-8";
    private boolean followRedirects = true;

    // 超时配置
    private Duration connectTimeout = Duration.ofSeconds(5);
    private Duration socketTimeout = Duration.ofSeconds(10);
    private Duration requestTimeout = Duration.ofSeconds(15);
    private Duration connectionRequestTimeout = Duration.ofSeconds(3);

    // 连接池配置
    private int maxConnectionsTotal = 200;
    private int maxConnectionsPerRoute = 50;
    private Duration connectionTTL = Duration.ofMinutes(5);
    private Duration validateAfterInactivity = Duration.ofSeconds(2);

    // 重试配置
    private boolean retryEnabled = true;
    private int maxRetries = 3;
    private Duration retryDelay = Duration.ofMillis(1000);
    private double retryBackoffMultiplier = 2.0;
    private Duration maxRetryDelay = Duration.ofSeconds(30);

    // 代理配置
    private String proxyHost = "";
    private int proxyPort = 8080;
    private String proxyUsername = "";
    private String proxyPassword = "";

    // SSL配置
    private boolean trustAllCertificates = false;
    private boolean hostnameVerification = true;

    // 压缩配置
    private boolean compressionEnabled = true;

    // 默认请求头
    private final Map<String, String> defaultHeaders = new HashMap<>();

    // 拦截器
    private final List<RestClientInterceptor> interceptors = new ArrayList<>();

    // 扩展
    private final List<RestClientExtension> extensions = new ArrayList<>();

    // 自定义配置
    private final Map<String, Object> customProperties = new HashMap<>();

    /**
     * 设置基础URL
     */
    public RestClientBuilder baseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
        return this;
    }

    /**
     * 设置基础URL（URI版本）
     */
    public RestClientBuilder baseUrl(URI baseUrl) {
        this.baseUrl = baseUrl.toString();
        return this;
    }

    /**
     * 设置User-Agent
     */
    public RestClientBuilder userAgent(String userAgent) {
        this.userAgent = userAgent;
        return this;
    }

    /**
     * 设置字符编码
     */
    public RestClientBuilder charset(String charset) {
        this.charset = charset;
        return this;
    }

    /**
     * 设置是否遵循重定向
     */
    public RestClientBuilder followRedirects(boolean followRedirects) {
        this.followRedirects = followRedirects;
        return this;
    }

    // 超时配置方法
    public RestClientBuilder connectTimeout(Duration timeout) {
        this.connectTimeout = timeout;
        return this;
    }

    public RestClientBuilder socketTimeout(Duration timeout) {
        this.socketTimeout = timeout;
        return this;
    }

    public RestClientBuilder requestTimeout(Duration timeout) {
        this.requestTimeout = timeout;
        return this;
    }

    public RestClientBuilder connectionRequestTimeout(Duration timeout) {
        this.connectionRequestTimeout = timeout;
        return this;
    }

    /**
     * 设置所有超时
     */
    public RestClientBuilder timeout(Duration timeout) {
        return connectTimeout(timeout)
                .socketTimeout(timeout)
                .requestTimeout(timeout)
                .connectionRequestTimeout(timeout);
    }

    // 连接池配置方法
    public RestClientBuilder maxConnectionsTotal(int maxConnections) {
        this.maxConnectionsTotal = maxConnections;
        return this;
    }

    public RestClientBuilder maxConnectionsPerRoute(int maxConnections) {
        this.maxConnectionsPerRoute = maxConnections;
        return this;
    }

    public RestClientBuilder connectionTTL(Duration ttl) {
        this.connectionTTL = ttl;
        return this;
    }

    public RestClientBuilder validateAfterInactivity(Duration duration) {
        this.validateAfterInactivity = duration;
        return this;
    }

    // 重试配置方法
    public RestClientBuilder enableRetry(boolean enabled) {
        this.retryEnabled = enabled;
        return this;
    }

    public RestClientBuilder maxRetries(int maxRetries) {
        this.maxRetries = maxRetries;
        return this;
    }

    public RestClientBuilder retryDelay(Duration delay) {
        this.retryDelay = delay;
        return this;
    }

    public RestClientBuilder retryBackoffMultiplier(double multiplier) {
        this.retryBackoffMultiplier = multiplier;
        return this;
    }

    public RestClientBuilder maxRetryDelay(Duration maxDelay) {
        this.maxRetryDelay = maxDelay;
        return this;
    }

    /**
     * 配置重试策略
     */
    public RestClientBuilder retryPolicy(RetryPolicy policy) {
        return enableRetry(true)
                .maxRetries(policy.getMaxAttempts())
                .retryDelay(policy.getInitialDelay())
                .retryBackoffMultiplier(policy.getBackoffMultiplier())
                .maxRetryDelay(policy.getMaxDelay());
    }

    // 代理配置方法
    public RestClientBuilder proxyHost(String host) {
        this.proxyHost = host;
        return this;
    }

    public RestClientBuilder proxyPort(int port) {
        this.proxyPort = port;
        return this;
    }

    public RestClientBuilder proxyCredentials(String username, String password) {
        this.proxyUsername = username;
        this.proxyPassword = password;
        return this;
    }

    /**
     * 设置代理
     */
    public RestClientBuilder proxy(String host, int port) {
        return proxyHost(host).proxyPort(port);
    }

    public RestClientBuilder proxy(String host, int port, String username, String password) {
        return proxyHost(host).proxyPort(port).proxyCredentials(username, password);
    }

    // SSL配置方法
    public RestClientBuilder trustAllCertificates(boolean trustAll) {
        this.trustAllCertificates = trustAll;
        return this;
    }

    public RestClientBuilder hostnameVerification(boolean enabled) {
        this.hostnameVerification = enabled;
        return this;
    }

    // 压缩配置方法
    public RestClientBuilder enableCompression(boolean enabled) {
        this.compressionEnabled = enabled;
        return this;
    }

    /**
     * 启用压缩
     */
    public RestClientBuilder enableCompression() {
        return enableCompression(true);
    }

    // 请求头配置方法
    public RestClientBuilder defaultHeader(String name, String value) {
        this.defaultHeaders.put(name, value);
        return this;
    }

    public RestClientBuilder defaultHeaders(Map<String, String> headers) {
        this.defaultHeaders.putAll(headers);
        return this;
    }

    /**
     * 批量设置请求头
     */
    public RestClientBuilder headers(String... keyValuePairs) {
        if (keyValuePairs.length % 2 != 0) {
            throw new IllegalArgumentException("键值对数量不匹配");
        }
        for (int i = 0; i < keyValuePairs.length; i += 2) {
            defaultHeader(keyValuePairs[i], keyValuePairs[i + 1]);
        }
        return this;
    }

    // 拦截器配置方法
    public RestClientBuilder addInterceptor(RestClientInterceptor interceptor) {
        this.interceptors.add(interceptor);
        return this;
    }

    public RestClientBuilder addInterceptors(List<RestClientInterceptor> interceptors) {
        this.interceptors.addAll(interceptors);
        return this;
    }

    public RestClientBuilder addInterceptor(Consumer<RequestContext> requestConsumer,
                                          Consumer<ResponseContext> responseConsumer) {
        return addInterceptor(new RestClientInterceptor() {
            @Override
            public void preRequest(RequestContext context) {
                if (requestConsumer != null) {
                    requestConsumer.accept(context);
                }
            }

            @Override
            public void postResponse(ResponseContext context) {
                if (responseConsumer != null) {
                    responseConsumer.accept(context);
                }
            }
        });
    }

    // 扩展配置方法
    public RestClientBuilder addExtension(RestClientExtension extension) {
        this.extensions.add(extension);
        return this;
    }

    public RestClientBuilder addExtensions(List<RestClientExtension> extensions) {
        this.extensions.addAll(extensions);
        return this;
    }

    /**
     * 添加指定类型的扩展
     */
    public RestClientBuilder addExtension(Class<? extends RestClientExtension> extensionClass) {
        try {
            RestClientExtension extension = extensionClass.getDeclaredConstructor().newInstance();
            return addExtension(extension);
        } catch (Exception e) {
            throw new RuntimeException("无法创建扩展实例: " + extensionClass.getName(), e);
        }
    }

    /**
     * 应用所有已注册的扩展
     */
    public RestClientBuilder applyAllExtensions() {
        return addExtensions(ExtensionRegistry.getAllExtensions());
    }

    /**
     * 应用指定分类的扩展
     */
    public RestClientBuilder applyExtensions(com.yang.core.extension.ExtensionPoint.Category category) {
        return addExtensions(ExtensionRegistry.getExtensions(category));
    }

    // 自定义配置方法
    public RestClientBuilder customProperty(String key, Object value) {
        this.customProperties.put(key, value);
        return this;
    }

    public RestClientBuilder customProperties(Map<String, Object> properties) {
        this.customProperties.putAll(properties);
        return this;
    }

    /**
     * 便捷配置方法 - 开发模式
     */
    public RestClientBuilder forDevelopment() {
        return trustAllCertificates(true)
                .hostnameVerification(false)
                .timeout(Duration.ofSeconds(30))
                .enableCompression(false)
                .addInterceptor(new LoggingInterceptor());
    }

    /**
     * 便捷配置方法 - 生产模式
     */
    public RestClientBuilder forProduction() {
        return trustAllCertificates(false)
                .hostnameVerification(true)
                .timeout(Duration.ofSeconds(10))
                .enableRetry(true)
                .maxRetries(3)
                .enableCompression(true);
    }

    /**
     * 便捷配置方法 - 高性能模式
     */
    public RestClientBuilder forHighPerformance() {
        return maxConnectionsTotal(500)
                .maxConnectionsPerRoute(100)
                .connectionTTL(Duration.ofMinutes(10))
                .validateAfterInactivity(Duration.ofSeconds(1))
                .enableCompression(true);
    }

    /**
     * 便捷配置方法 - 高并发模式
     */
    public RestClientBuilder forHighConcurrency() {
        return maxConnectionsTotal(1000)
                .maxConnectionsPerRoute(200)
                .connectionTTL(Duration.ofMinutes(30))
                .enableRetry(false)
                .timeout(Duration.ofSeconds(5));
    }

    /**
     * 构建RestClient实例
     */
    public RestClient build() {
        validateConfiguration();

        RestClientConfig config = createConfig();
        return new RestClient(config);
    }

    /**
     * 验证配置
     */
    private void validateConfiguration() {
        if (maxConnectionsTotal <= 0) {
            throw new IllegalArgumentException("最大连接数必须大于0");
        }
        if (maxConnectionsPerRoute <= 0) {
            throw new IllegalArgumentException("每路由最大连接数必须大于0");
        }
        if (maxConnectionsPerRoute > maxConnectionsTotal) {
            throw new IllegalArgumentException("每路由最大连接数不能大于总连接数");
        }
        if (retryBackoffMultiplier <= 1.0) {
            throw new IllegalArgumentException("重试退避倍数必须大于1.0");
        }
    }

    /**
     * 创建配置对象
     */
    private RestClientConfig createConfig() {
        return RestClientConfig.builder()
                .baseUrl(baseUrl)
                .userAgent(userAgent)
                .charset(charset)
                .followRedirects(followRedirects)
                .connectTimeout(connectTimeout)
                .socketTimeout(socketTimeout)
                .requestTimeout(requestTimeout)
                .connectionRequestTimeout(connectionRequestTimeout)
                .maxConnectionsTotal(maxConnectionsTotal)
                .maxConnectionsPerRoute(maxConnectionsPerRoute)
                .connectionTTL(connectionTTL)
                .validateAfterInactivity(validateAfterInactivity)
                .retryEnabled(retryEnabled)
                .maxRetries(maxRetries)
                .retryDelay(retryDelay)
                .retryBackoffMultiplier(retryBackoffMultiplier)
                .maxRetryDelay(maxRetryDelay)
                .proxyHost(proxyHost)
                .proxyPort(proxyPort)
                .proxyUsername(proxyUsername)
                .proxyPassword(proxyPassword)
                .trustAllCertificates(trustAllCertificates)
                .hostnameVerification(hostnameVerification)
                .compressionEnabled(compressionEnabled)
                .defaultHeaders(new HashMap<>(defaultHeaders))
                .interceptors(new ArrayList<>(interceptors))
                .extensions(new ArrayList<>(extensions))
                .customProperties(new HashMap<>(customProperties))
                .build();
    }

    /**
     * 重置构建器
     */
    public RestClientBuilder reset() {
        return new RestClientBuilder();
    }

    /**
     * 复制构建器
     */
    public RestClientBuilder copy() {
        RestClientBuilder copy = new RestClientBuilder();
        // 复制所有属性
        copy.baseUrl = this.baseUrl;
        copy.userAgent = this.userAgent;
        copy.charset = this.charset;
        copy.followRedirects = this.followRedirects;
        // ... 复制其他属性
        return copy;
    }

    /**
     * 静态工厂方法
     */
    public static RestClientBuilder builder() {
        return new RestClientBuilder();
    }

    /**
     * 创建默认构建器
     */
    public static RestClientBuilder create() {
        return new RestClientBuilder();
    }

    /**
     * 创建开发环境构建器
     */
    public static RestClientBuilder forDev() {
        return new RestClientBuilder().forDevelopment();
    }

    /**
     * 创建生产环境构建器
     */
    public static RestClientBuilder forProd() {
        return new RestClientBuilder().forProduction();
    }
}